#include "stdafx.h"
#include "VS2010CtxMenuFixApp.h"

// Forward declarations of functions included in this code module:
static INT_PTR AboutDlgInit(HWND, UINT, WPARAM, LPARAM);
static TCHAR* GetAppVersion();

INT_PTR CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        return AboutDlgInit(hDlg, message, wParam, lParam);

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }

    return (INT_PTR)FALSE;
}

static INT_PTR AboutDlgInit(HWND hDlg, UINT message, WPARAM wParam, LPARAM)
{
    SetDlgItemText(hDlg, IDC_APP_TITLE, g_cAppResources->GetAppTitle());

    TCHAR* version = GetAppVersion();
    if (version)
    {
        SetDlgItemText(hDlg, IDC_APP_VERSION, version);
        delete version;
    }

    RECT rcDialog;
    RECT rcDesktop;

    GetWindowRect(hDlg, &rcDialog);
    int dlgWidth = rcDialog.right - rcDialog.left;
    int dlgHeight = rcDialog.bottom - rcDialog.top;

    GetWindowRect(GetDesktopWindow(), &rcDesktop);
    int dskWidth = rcDesktop.right - rcDesktop.left;
    int dskHeight = rcDesktop.bottom - rcDesktop.top;

    SetWindowPos(hDlg, HWND_TOP, rcDesktop.left + (dskWidth - dlgWidth) / 2, rcDesktop.top + (dskHeight - dlgHeight) / 2, 0, 0, SWP_NOSIZE);

    return (INT_PTR)TRUE;
}

static TCHAR* GetAppVersion()
{
    TCHAR szProcessFileName[MAX_PATH + 1];
    if (!GetModuleFileNameEx(GetCurrentProcess(), NULL, szProcessFileName, MAX_PATH + 1))
    {
        return NULL;
    }

    DWORD dwHandle;
    DWORD dwSize = GetFileVersionInfoSize(szProcessFileName, &dwHandle);
    if (!dwSize)
    {
        return NULL;
    }

    LPVOID vi = LocalAlloc(LMEM_FIXED, dwSize);
    if (!vi)
    {
        return NULL;
    }

    if (!GetFileVersionInfo(szProcessFileName, 0, dwSize, vi))
    {
        LocalFree(vi);
        return NULL;
    }

    VS_FIXEDFILEINFO* ffi;
    UINT uLen;
    if (!VerQueryValue(vi, __TEXT("\\"), (LPVOID*)(&ffi), &uLen))
    {
        LocalFree(vi);
        return NULL;
    }

    TCHAR* version = new TCHAR[32];
    wsprintf(version, __TEXT("Version %d.%d.%d.%d"), HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));

    LocalFree(vi);

    return version;
}
